package com.km.team.phsystem.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.km.team.phsystem.beans.pojo.*;
import com.km.team.phsystem.beans.vo.QueueCombinedInformationVo;
import com.km.team.phsystem.beans.vo.QueueInfoCombinationVo;
import com.km.team.phsystem.beans.vo.QueueInfoVo;
import com.km.team.phsystem.beans.vo.QueueListAndStartTimeToStringVo;
import com.km.team.phsystem.common.enums.QueueStatusEnum;
import com.km.team.phsystem.common.enums.ReservationTypeEnum;
import com.km.team.phsystem.common.enums.ResultEnum;
import com.km.team.phsystem.common.exception.SystemErrorException;
import com.km.team.phsystem.common.utils.LocalDateUtil;
import com.km.team.phsystem.dao.mybatis.QueueConfigMapper;
import com.km.team.phsystem.dao.mybatis.QueueInfoMapper;
import com.km.team.phsystem.dao.mybatis.custom.QueueInfoMapperCustom;
import com.km.team.phsystem.service.IQueueService;
import com.km.team.phsystem.service.ISysBusiTypeService;
import com.km.team.phsystem.service.TemporaryAppointmentService;
import com.km.team.phsystem.service.impl.base.BaseService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Author: jiangjun
 * Date: 2018/10/15
 * Time: 下午5:13
 * Description:
 */
@Service("queueService")
public class QueueServiceImpl extends BaseService<QueueServiceImpl, QueueInfo>
    implements IQueueService {

    private static final String YYY_MM_DD = "yyyy-MM-dd";
    private static final String HH_MM = "HH:mm";

    private final QueueInfoMapper mapper;
    private final QueueInfoMapperCustom queueInfoMapperCustom;
    private final QueueConfigMapper configMapper;
    private final ISysBusiTypeService iSysBusiTypeService;
    private final TemporaryAppointmentService temporaryAppointmentService;

    @Autowired
    public QueueServiceImpl(QueueInfoMapper mapper,
                            QueueInfoMapperCustom queueInfoMapperCustom, QueueConfigMapper configMapper,
                            ISysBusiTypeService iSysBusiTypeService,
                            TemporaryAppointmentService temporaryAppointmentService) {
        this.mapper = mapper;
        this.queueInfoMapperCustom = queueInfoMapperCustom;
        this.configMapper = configMapper;
        this.iSysBusiTypeService = iSysBusiTypeService;
        this.temporaryAppointmentService = temporaryAppointmentService;
    }

    /**
     * 根据电话获取正在排号列表
     *
     * @param mobile
     * @return
     * @throws Exception
     */
    @Override
    public List<QueueInfo> getQueueingByMobileAndBusiness(String mobile) throws Exception {
        if (StringUtils.isBlank(mobile)) {
            return null;
        }
        List<String> statusList = assemblyStatusList();
        QueueInfoExample example = new QueueInfoExample();
        example.or().andMobileEqualTo(mobile)
            .andQueueStatusIn(statusList);
        return mapper.selectByExample(example);
    }


    @Override
    public List<QueueInfo> getQueueingByMobileAndBusiness(String mobile, String busiType) throws Exception {
        if (StringUtils.isBlank(mobile) && StringUtils.isBlank(busiType)) {
            return null;
        }
        QueueInfoExample example = new QueueInfoExample();
        example.or().andMobileEqualTo(mobile)
            .andBusiTypeEqualTo(busiType)
            .andQueueStatusIn(assemblyStatusList());
        return mapper.selectByExample(example);
    }

    @Override
    public void cancel(Integer id) {
        if (id == null || id <= 0) {
            return;
        }
        QueueInfo queueInfo = super.baseGet(id);
        queueInfo.setQueueStatus(QueueStatusEnum.QUEUE_STATUS_USER_CANCEL.getType());
        queueInfo.setUpdateTime(new Date());
        //维护某些关联数据库
        if (ReservationTypeEnum.RESERVATION_TYPE_TEMPORARY_APPOINTMENT.getType().equals(queueInfo.getQueueType())) {
            this.temporaryAppointmentService.reduceOne(Integer.valueOf(queueInfo.getBusiType()));
        }
        super.baseUpdate(queueInfo);
    }

    @Override
    public QueueInfo getDataById(Integer id) throws Exception {
        return super.baseGet(id);
    }

    @Override
    public void dispatch(Integer queueId, Integer userId) throws Exception {
        QueueInfo queueInfo = super.baseGet(queueId);
        queueInfo.setQueueStatus(QueueStatusEnum.QUEUE_STATUS_DISPATCHED.getType());
        queueInfo.setUserId(userId);
        queueInfo.setUpdateTime(new Date());
        super.baseUpdate(queueInfo);
    }

    @Override
    public int updateNotifyInfo(Integer queueId, String queueCode, String notifyInfo) throws Exception {
        if (queueId == null && StringUtils.isBlank(queueCode)) {
            return 0;
        }
        QueueInfo record = new QueueInfo();
        QueueInfoExample example = new QueueInfoExample();
        QueueInfoExample.Criteria criteria = example.or();

        if (queueId != null) {
            record.setId(queueId);
            criteria.andIdEqualTo(queueId);
        }
        if (StringUtils.isNotBlank(queueCode)) {
            record.setQueueCode(queueCode);
            criteria.andQueueCodeEqualTo(queueCode);
        }
        record.setNotifyInfo(notifyInfo);
        record.setQueueStatus(QueueStatusEnum.QUEUE_STATUS_MSG_SENDED.getType());
        record.setUpdateTime(new Date());
        return mapper.updateByExampleSelective(record, example);
    }

    @Override
    public QueueInfo getDataByQueueCode(String queueCode) throws Exception {
        QueueInfoExample example = new QueueInfoExample();
        example.or().andQueueCodeEqualTo(queueCode)
            .andQueueStatusEqualTo(QueueStatusEnum.QUEUE_STATUS_RESERVED.getType());
        List<QueueInfo> list = mapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public QueueInfo getDataForKey(Integer key) {
        return this.mapper.selectByPrimaryKey(key);
    }

    /**
     * 根据{@link QueueInfo}的主键跟新排号状态
     *
     * @param queueInfo 数据
     * @return
     */
    @Override
    public int updateQueueStatusForKey(QueueInfo queueInfo) {
        return this.mapper.updateByPrimaryKey(queueInfo);
    }

    /**
     * 根据电话号码查询详细数据
     * 数由三个数据表组成
     * 由排号数据表{@link QueueInfo} 以及排号所选的日期表{@link DatePhConfig}
     * 以及排号所选的业务类型下的排号时间段表{@link TimeSlotPhConfig} 组成
     * 其中{@link QueueCombinedInformationVo} 对数据进行了封装，组合了{@link QueueInfo}，同时纳入了 日期表的ID 和具体日期
     * 及时段表的ID 和 开始时间和结束时间（时段信息）
     *
     * @param mobile {@link QueueInfo}的主键
     * @return
     */
    @Override
    public List<QueueInfo> getDataForMobile(String mobile) {
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or().andQueueStatusIn(assemblyStatusList())
            .andMobileEqualTo(mobile);
        List<QueueInfo> resultList = this.mapper.selectByExample(queueInfoExample);
        return resultList;
    }

    @Override
    public QueueInfo selectQueueById(Integer id) {
        return this.mapper.selectByPrimaryKey(id);
    }

    /**
     * 根据业务ID列表获取当天所有时段的排号消息
     * 需要更具时段进行分组
     *
     * @param businessIdList 业务ID列表
     * @return
     */
    @Override
    public List<QueueListAndStartTimeToStringVo> queueListByBusinessIdList(List<Integer> businessIdList,
                                                                           String dateStr) throws Exception {
        Date date = DateUtil.parse(dateStr);
        if (CollectionUtils.isEmpty(businessIdList)) {
            //查询所有类型
            List<SystemBusitype> sysBusiTypeDataList = this.iSysBusiTypeService.getSysBusiTypeData();
            sysBusiTypeDataList.forEach(item -> businessIdList.add(item.getId()));
        }
        List<String> idStrings = businessIdList.stream().map(String::valueOf).collect(Collectors.toList());

        //根据日期-时段表ID，查询所有排号
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or().andDateEqualTo(date)
            .andQueueStatusIn(new ArrayList<>(Arrays.asList(QueueStatusEnum.QUEUE_STATUS_MSG_SENDED.getType(),
                QueueStatusEnum.QUEUE_STATUS_RESERVED.getType(), QueueStatusEnum.QUEUE_STATUS_SKIP.getType(),
                QueueStatusEnum.QUEUE_STATUS_DISPATCHED.getType())))
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType())
            .andBusiTypeIn(idStrings);
        queueInfoExample.setOrderByClause("create_time asc,queue_status asc");
        List<QueueInfo> queueInfoList = this.mapper.selectByExample(queueInfoExample);
        //开始组装
        List<QueueListAndStartTimeToStringVo> resultList = getQueueListAndStartTimeToStringVos();
        queueInfoList.forEach(item -> {
            QueueInfoCombinationVo queueInfoCombinationVo = new QueueInfoCombinationVo(item,
                item.getBusinessName(), item.getQueueCode());

            switch (item.getTimeSlotStartStart()) {
                case "09:00":
                    resultList.get(0).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
                case "10:00":
                    resultList.get(1).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
                case "11:00":
                    resultList.get(2).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
                case "13:00":
                    resultList.get(3).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
                case "14:00":
                    resultList.get(4).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
                case "15:00":
                    resultList.get(5).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
                default:
                    resultList.get(6).getQueueInfoList().add(queueInfoCombinationVo);
                    break;
            }
        });
        return resultList;
    }

    @Override
    public void registrationWindAndQueueId(Integer wind, Integer id) {
        QueueInfo queueInfo = this.mapper.selectByPrimaryKey(id);
        queueInfo.setWindowId(String.valueOf(wind));
        queueInfo.setQueueStatus(QueueStatusEnum.QUEUE_STATUS_DISPATCHED.getType());
        this.mapper.updateByPrimaryKeySelective(queueInfo);
    }

    @Override
    public List<QueueInfo> selectTemporaryQueue(List<String> idList, String date) throws Exception {
        this.temporaryAppointmentService.judgingDate();
        if (CollectionUtils.isEmpty(idList)) {
            //查询所有
            List<SystemBusitype> sysBusiTypeDataList = this.iSysBusiTypeService.getSysBusiTypeData();
            sysBusiTypeDataList.forEach(item -> idList.add(String.valueOf(item.getId())));
        }

        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or().andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_TEMPORARY_APPOINTMENT.getType())
            .andQueueStatusIn(Arrays.asList(QueueStatusEnum.QUEUE_STATUS_RESERVED.getType(),
                QueueStatusEnum.QUEUE_STATUS_SKIP.getType(),
                QueueStatusEnum.QUEUE_STATUS_DISPATCHED.getType(),
                QueueStatusEnum.QUEUE_STATUS_MSG_SENDED.getType()))
            .andBusiTypeIn(idList)
            .andDateEqualTo(DateUtil.parse(date, "yyyy-MM-dd"));
        queueInfoExample.setOrderByClause("create_time asc");
        return this.mapper.selectByExample(queueInfoExample);

    }

    @Override
    public List<QueueInfo> getDateForBusinessId(Integer businessId) {
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or().andBusiTypeEqualTo(String.valueOf(businessId))
            .andQueueStatusIn(assemblyStatusList());
        return this.mapper.selectByExample(queueInfoExample);

    }

    @Override
    public Long selectQueueNumFotBusinessIdAndDate(Integer businessId, Date date) {
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or()
            //业务类型
            .andBusiTypeEqualTo(String.valueOf(businessId))
            //日期
            .andDateEqualTo(date)
            //排号状体
            .andQueueStatusNotEqualTo(QueueStatusEnum.QUEUE_STATUS_USER_CANCEL.getType())
            //排号类型
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType());
        return this.mapper.countByExample(queueInfoExample);
    }

    @Override
    public Long selectQueueNumFotBusinessIdAndDateAndTimeSlot(Integer businessId, Date date, Integer timeSlotId) {
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or()
            //业务类型
            .andBusiTypeEqualTo(String.valueOf(businessId))
            //日期
            .andDateEqualTo(date)
            //排号状体
            .andQueueStatusNotEqualTo(QueueStatusEnum.QUEUE_STATUS_USER_CANCEL.getType())
            //排号类型
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType())
            //时段
            .andTimeSlotIdEqualTo(timeSlotId);
        return this.mapper.countByExample(queueInfoExample);
    }

    /**
     * 获取当前时间的队列
     *
     * @param idList
     * @return
     */
    @Override
    public QueueListAndStartTimeToStringVo getNowTimeQueueList(List<String> idList, String windowId, Date dateTime) {
        LocalTime time = LocalTime.now().withSecond(0).withNano(0);

        if (time.getHour() < 9 || time.getHour() > 17) {
            //不再业务受理时间范围
            return new QueueListAndStartTimeToStringVo();
        }
        if (CollectionUtils.isEmpty(idList)) {
            //查询所有类型
            try {
                this.iSysBusiTypeService.getSysBusiTypeData().forEach(item -> idList.add(String.valueOf(item.getId())));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        //
        queueInfoExample.or()
            //已预约和以发生
            .andWindowIdEqualTo(windowId)
            .andQueueStatusEqualTo(QueueStatusEnum.QUEUE_STATUS_PROCESS_START
                .getType())
            //业务列表
//            .andBusiTypeIn(idList)
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType())
            .andDateEqualTo(DateUtil.beginOfDay(dateTime));
        queueInfoExample.setOrderByClause("create_time asc");
        List<QueueInfo> queueInfoListFor3Status = this.mapper.selectByExample(queueInfoExample);
        List<Integer> existenceList = new ArrayList<>();
        queueInfoListFor3Status.forEach(item -> existenceList.add(item.getId()));

        time = LocalTime.now().withMinute(0).withSecond(0).withMinute(0);
        String nowTime = time.format(DateTimeFormatter.ofPattern(HH_MM));
        queueInfoExample.clear();
        queueInfoExample.setOrderByClause("create_time asc,queue_status asc");
        QueueInfoExample.Criteria criteria = queueInfoExample.createCriteria()
            //已预约和以发生
            .andQueueStatusIn(assemblyStatusList())
            //业务列表
            .andBusiTypeIn(idList)
            // 按时间降序
            .andTimeSlotStartStartEqualTo(nowTime)

            .andDateEqualTo(DateUtil.beginOfDay(dateTime))
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType());
        if (CollectionUtil.isNotEmpty(existenceList)) {
            criteria.andIdNotIn(existenceList);
        }
        List<QueueInfo> queueInfos = null;
        if (LocalTime.now().getMinute() <= 30) {
            //or连接
            LocalTime timeOr = LocalTime.now().withMinute(0).withSecond(0).withMinute(0).minusHours(1);
            String oldTime = timeOr.format(DateTimeFormatter.ofPattern(HH_MM));
            QueueInfoExample.Criteria criteria2 = queueInfoExample.createCriteria()
                //已预约和以发生
                .andQueueStatusIn(assemblyStatusList())
                //业务列表
                .andBusiTypeIn(idList)
                // 按时间降序
                .andTimeSlotStartStartEqualTo(oldTime)
                .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType())
                .andDateEqualTo(DateUtil.beginOfDay(dateTime));
            if (CollectionUtil.isNotEmpty(existenceList)) {
                criteria2.andIdNotIn(existenceList);
            }
            queueInfoExample.or(criteria2);
            queueInfos = this.mapper.selectByExample(queueInfoExample);
            queueInfoListFor3Status.addAll(queueInfos);
        } else {
            //只需要查询当前时段
            queueInfos = this.mapper.selectByExample(queueInfoExample);
            queueInfoListFor3Status.addAll(queueInfos);
            //需要做超时操作
            queueInfoExample.clear();

            queueTimeOut(queueInfoExample);

        }


        QueueListAndStartTimeToStringVo result = null;
        if (CollectionUtils.isEmpty(queueInfoListFor3Status)) {
            //返回临时号：
            queueInfoExample.clear();
            queueInfoExample.setOrderByClause("create_time asc,queue_status asc");
            queueInfoExample.or().andQueueStatusIn(Arrays.asList(QueueStatusEnum.QUEUE_STATUS_RESERVED.getType(),
                QueueStatusEnum.QUEUE_STATUS_MSG_SENDED.getType(), QueueStatusEnum.QUEUE_STATUS_DISPATCHED.getType()))
                //临时预约
                .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_TEMPORARY_APPOINTMENT.getType())
                .andBusiTypeIn(idList).andDateEqualTo(DateUtil.beginOfDay(dateTime));
            List<QueueInfo> list = this.mapper.selectByExample(queueInfoExample);
            queueInfoListFor3Status.addAll(list);

            if (CollectionUtils.isEmpty(queueInfoListFor3Status)) {
                result = new QueueListAndStartTimeToStringVo();
                result.setStartTime(nowTime);
                result.setSize(0);
                result.setEndTime(time.plusHours(1).format(DateTimeFormatter.ofPattern(HH_MM)));
                return result;
            }
        }
        result = new QueueListAndStartTimeToStringVo();
        result.setStartTime(nowTime);
        result.setSize(queueInfoListFor3Status.size());
        result.setEndTime(time.plusHours(1).format(DateTimeFormatter.ofPattern(HH_MM)));
        List<QueueInfoCombinationVo> queueInfoList = result.getQueueInfoList();
        queueInfoListFor3Status.forEach(item -> queueInfoList.add(new QueueInfoCombinationVo(item,
            item.getBusinessName(),
            item.getQueueCode())));
        result.setQueueInfoList(queueInfoList);
        return result;

    }

    private void queueTimeOut(QueueInfoExample queueInfoExample) {
        QueueInfoExample.Criteria timeOutCriteria = queueInfoExample.createCriteria();
        LocalTime time = LocalTime.now().withMinute(0).withSecond(0).withMinute(0).minusHours(1);
        List<String> timeOutTimeList = new ArrayList<>(Arrays.asList("08:00"));
        for (int i = time.getHour(); i >= 9; i--) {
            switch (i) {
                case 17:
                    timeOutTimeList.add("17:00");
                    break;
                case 16:
                    timeOutTimeList.add("16:00");
                    break;
                case 15:
                    timeOutTimeList.add("15:00");
                    break;
                case 14:
                    timeOutTimeList.add("14:00");
                    break;
                case 13:
                    timeOutTimeList.add("13:00");
                    break;
                case 11:
                    timeOutTimeList.add("11:00");
                    break;
                case 10:
                    timeOutTimeList.add("10:00");
                    break;
                case 9:
                    timeOutTimeList.add("09:00");
                    break;
                default:
                    break;
            }
        }
        timeOutCriteria
            .andTimeSlotStartStartIn(timeOutTimeList)
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType())
            .andDateLessThanOrEqualTo(DateUtil.beginOfDay(new Date()))
            .andQueueStatusEqualTo(QueueStatusEnum.QUEUE_STATUS_SKIP.getType());
        List<QueueInfo> timeOutList = this.mapper.selectByExample(queueInfoExample);
        timeOutList.forEach(item -> {
            logger.info(item.getMobile() + " 用户的 " + item.getBusinessName() + " 业务已超时！");
            item.setQueueStatus(QueueStatusEnum.QUEUE_STATUS_TERMINATE.getType());
        });
        if (CollectionUtils.isNotEmpty(timeOutList)) {
            int i = this.queueInfoMapperCustom.batchUpdateForTimeOut(timeOutList);
            logger.info("批量跟超时新成功! 跟新数量： " + i);
        }
    }

    @Override
    public List<QueueInfo> selectDataForDateAfter(Integer businessId, DateTime beginOfDay) {
        QueueInfoExample queueInfoExample = new QueueInfoExample();
        queueInfoExample.or()
            //业务类型
            .andBusiTypeEqualTo(String.valueOf(businessId))
            //日期
            .andDateGreaterThanOrEqualTo(beginOfDay)
            //排号状体
            .andQueueStatusNotEqualTo(QueueStatusEnum.QUEUE_STATUS_USER_CANCEL.getType())
            //排号类型
            .andQueueTypeEqualTo(ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType());
        return this.mapper.selectByExample(queueInfoExample);


    }

    private List<QueueListAndStartTimeToStringVo> getQueueListAndStartTimeToStringVos() {
        QueueListAndStartTimeToStringVo setStart9 =
            new QueueListAndStartTimeToStringVo("09:00", "10:00");
        QueueListAndStartTimeToStringVo setStart10 =
            new QueueListAndStartTimeToStringVo("10:00", "11:00");
        QueueListAndStartTimeToStringVo setStart11 =
            new QueueListAndStartTimeToStringVo("11:00", "12:00");
        QueueListAndStartTimeToStringVo setStart13 =
            new QueueListAndStartTimeToStringVo("13:00", "14:00");
        QueueListAndStartTimeToStringVo setStart14 =
            new QueueListAndStartTimeToStringVo("14:00", "15:00");
        QueueListAndStartTimeToStringVo setStart15 =
            new QueueListAndStartTimeToStringVo("15:00", "16:00");
        QueueListAndStartTimeToStringVo setStart16 =
            new QueueListAndStartTimeToStringVo("16:00", "17:00");
        List<QueueListAndStartTimeToStringVo> resultList = new ArrayList<>(7);
        resultList.add(setStart9);
        resultList.add(setStart10);
        resultList.add(setStart11);
        resultList.add(setStart13);
        resultList.add(setStart14);
        resultList.add(setStart15);
        resultList.add(setStart16);
        return resultList;
    }

    @Transactional
    @Override
    public String add(QueueInfoVo vo) {
        if (vo == null) {
            return null;
        }
//        String queueCode = genQueueCode(vo);
        QueueConfigExample queueConfigExample = new QueueConfigExample();
        List<QueueConfig> configList = configMapper.selectByExample(new QueueConfigExample());
        if (CollectionUtils.isEmpty(configList)) {
            throw new SystemErrorException(ResultEnum.ERROR.getCode(), ResultEnum.ERROR.getMessage(),
                "没有配置队列信息！");
        }
        QueueConfig config = null;
        if (ReservationTypeEnum.RESERVATION_TYPE_TEMPORARY_APPOINTMENT.getType().equals(vo.getReservationType())) {
            queueConfigExample.or().andPrefixEqualTo("C");
            List<QueueConfig> configs = this.configMapper.selectByExample(queueConfigExample);
            if (!CollectionUtils.isEmpty(configs)) {
                config = configs.get(0);
            }
        } else {
            //固定排号
            queueConfigExample.or().andPrefixEqualTo("A");
            List<QueueConfig> configs = this.configMapper.selectByExample(queueConfigExample);
            if (!CollectionUtils.isEmpty(configs)) {
                config = configs.get(0);
            }
        }
        Integer maxId = config.getQuqueSequence();
        if (maxId > 9999) {
            maxId = 0;
        }
        maxId = ++maxId;
        // 更新序列
        config.setQuqueSequence(maxId);
        configMapper.updateByPrimaryKeySelective(config);
        // 更新排号信息
        String queueCode = genQueueCode(config.getPrefix(), maxId);
        QueueInfo queueInfo = new QueueInfo();
        queueInfo.setMobile(vo.getMobile());
        queueInfo.setBusiType(vo.getBusiType());
        queueInfo.setName(vo.getName());
        queueInfo.setBusinessName(vo.getBusiTypeName());
        queueInfo.setQueueStatus(QueueStatusEnum.QUEUE_STATUS_RESERVED.getType());
        queueInfo.setQueueCode(queueCode);
        queueInfo.setQueueType(vo.getReservationType());
        if (ReservationTypeEnum.RESERVATION_TYPE_FIXED_APPOINTMENT.getType().equals(vo.getReservationType())) {
            queueInfo.setTimeSlotId(Integer.valueOf(vo.getQueueTimeSloeId()));
            queueInfo.setTimeSlotStartStart(vo.getQueueTimeSloeStart());
            queueInfo.setTimeSlotStartEnd(vo.getQueueTimeSloeEnd());
            queueInfo.setDate(LocalDateUtil.stampToDate(vo.getQueueDate()));

        } else {
//            queueInfo.setDate(DateUtil.parse(DateUtil.formatDate(new Date()), YYY_MM_DD));
            queueInfo.setDate(LocalDateUtil.stampToDate(vo.getQueueDate()));
            this.temporaryAppointmentService.addOne(Integer.valueOf(vo.getBusiType()));
        }
        super.baseUpdate(queueInfo);
        return queueCode;
    }


    /**
     * 生成排队号【简单实现】
     *
     * @param
     * @return
     */
    private String genQueueCode(String prefix, Integer sequence) {
        String count = String.format("%06d", sequence);
        return prefix + count;
    }

    /**
     * 组装排队状态
     *
     * @return
     */
    private List<String> assemblyStatusList() {
        List<String> statusList = new ArrayList<>();
        statusList.add(QueueStatusEnum.QUEUE_STATUS_RESERVED.getType());
        statusList.add(QueueStatusEnum.QUEUE_STATUS_MSG_SENDED.getType());
        statusList.add(QueueStatusEnum.QUEUE_STATUS_DISPATCHED.getType());
        statusList.add(QueueStatusEnum.QUEUE_STATUS_PROCESS_START.getType());
        return statusList;
    }


}
